﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Nirvana
{
    [ExecuteInEditMode]
    public abstract class UIEventBind : MonoBehaviour
    {

        [Tooltip("The event table for this bind.")]
        [SerializeField]
        private UIEventTable eventTable;
        /// <summary>
        /// 对应此事件的对象组
        /// </summary>
        private Dictionary<string, LinkedListNode<Component>> componentmap = new Dictionary<string, LinkedListNode<Component>>(StringComparer.Ordinal);
        public UIEventTable EventTable { get { return eventTable; } private set { eventTable = value; } }
        protected abstract void RefreshBind();

        protected virtual void Awake()
        {
            this.Binds();
        }
        void OnDestroy()
        {
            this.UnbindVariables();
        }

#if UNITY_EDITOR
        protected void OnValidate()
        {
            this.UnbindVariables();
            this.Binds();
            this.RefreshBind();
        }
#endif

        private void Binds()
        {
            if (this.eventTable == null)
            {
                this.eventTable = this.GetComponentInParentHard<UIEventTable>();
            }
        }
        private void UnbindVariables()
        {
            if (this.eventTable != null)
            {
                this.eventTable.ClearAllEvents();
                foreach (var p in this.componentmap)
                {
                    this.eventTable.RemoveComp(p.Key, p.Value);
                }
            }
            this.componentmap.Clear();
        }

        public SignalEvent GetSignalEvent(string eventName)
        {
            if (this.eventTable != null)
            {
                SignalEvent _event = this.eventTable.GetSignalEvent(eventName);
                if (_event != null)
                {
                    LinkedListNode<Component> linkedListNode;
                    if (this.componentmap.TryGetValue(eventName, out linkedListNode))
                    {
                        this.eventTable.RemoveComp(eventName, linkedListNode);
                        this.componentmap.Remove(eventName);
                    }
                    linkedListNode = this.eventTable.AddComp(eventName, this);
                    this.componentmap.Add(eventName, linkedListNode);
                }
                return _event;
            }
            return null;
        }

    }
}

